<?php

namespace app\ctrl;

use app\model\GroupInfo;
use app\model\JumpStat1;
use app\model\JumpStatDomain;
use core\lib\Redis;
use CacheKey;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

/**
 * 组号统计，并返回每条结果
 */
class Groupstat extends \app\ctrl\BaseController
{
    const COUNTRY_MAP = [
        'de' => '德国', 'it' => '意大利', 'jp' => '日本', 'fr' => '法国', 'us' => '美国'
    ];

    /**
     * 保存提交的跳转数据
     */
    public function commit()
    {
        return true;
        // 获取参数
        $post = post();
        $groupNo = strtolower(trim($post['group_no'] ?? ""));
        $domain = strtolower(trim($post['domain'] ?? ""));
        $ipAddress = trim($post['ip_address'] ?? "");
        $userAgent = trim($post['user_agent'] ?? "");
        $redis = new Redis();
        $today = date('Y-m-d');
        $errCacheKey1 = sprintf(CacheKey::GROUPBOT_NUM, $groupNo, $today);
        $errCacheKey2 = sprintf(CacheKey::IPERR_NUM, $groupNo, $today);

        if (!empty($userAgent) && str_contains($userAgent, 'bot')) {
            $num = $redis->get($errCacheKey1);
            if ($num === false) {
                $redis->set($errCacheKey1, 1);
            } else {
                $redis->incr($errCacheKey1);
            }
            return true;
        }
        if (!empty($ipAddress) && in_array($ipAddress, ['127.0.0.1', '0.0.0.0'])) {
            $num = $redis->get($errCacheKey2);
            if ($num === false) {
                $redis->set($errCacheKey2, 1);
            } else {
                $redis->incr($errCacheKey2);
            }
            return true;
        }

        $cacheKey1 = sprintf(CacheKey::GROUPNO_DOMAINS, $groupNo);
        $cacheKey2 = sprintf(CacheKey::STATDOMAIN, $today, $groupNo);
        $cacheKey3 = sprintf(CacheKey::JUMPINFO, $today, $groupNo, $domain);

        // 添加到该组号的域名集合中
        $redis->sadd($cacheKey1, $domain);

        // 添加日期+组号的统计信息
        $num = $redis->get($cacheKey2);
        if ($num === false) {
            $redis->set($cacheKey2, 1);
            $redis->expire($cacheKey2, CacheKey::STATDOMAIN_EXPIRE);
        } else {
            $redis->incr($cacheKey2);
        }

        // 添加跳转信息
        $num = $redis->get($cacheKey3);
        if ($num === false) {
            $redis->set($cacheKey3, 1);
            $redis->expire($cacheKey3, CacheKey::JUMPINFO_EXPIRE);
        } else {
            $redis->incr($cacheKey3);
        }
        // TODO：这边是浪费了ip_address和user_agent这两个参数

        return true;
    }

    /**
     * 显示统计视图1-全局汇总
     */
    public function index()
    {
        $view = new \core\lib\View(VIEWS);
        // 所有组号
        $groupNos = array_unique((new GroupInfo())->listAll(['ORDER' => ['id' => 'DESC']], 'group_no'));
        return $view->render('groupstat_detail', [
            'v' => time(),
            'group_nos' => $groupNos
        ]);
    }

    /**
     * 异步获取首页的数据
     */
    public function getIndexData()
    {
        // 获取组号信息
        $page = intval(post('page', 1));
        $pageSize = intval(post('limit', 20));
        $groupNo = trim(post('group_no', ''));

        $groupModel = new GroupInfo();
        $where['ORDER'] = ['id' => 'DESC'];
        !empty($groupNo) && $where['group_no'] = $groupNo;
        $list = $groupModel->lists($page, $pageSize, $where);
        $total = $groupModel->rowsCount($where);

        // 得到国家
        if (!empty($list)) {
            foreach ($list as &$item) {
                if (isset(self::COUNTRY_MAP[$item['country']])) {
                    $item['country'] = self::COUNTRY_MAP[$item['country']];
                }
            }
        }

        layuiRet($list, $total);
    }

    /**
     * 保存组信息的某个字段信息
     */
    public function saveGroupField()
    {
        $id = intval(post('id', 0));
        $field = trim(post('field', ''));
        $value = trim(post('value', ''));
        $groupModel = new GroupInfo();
        $group = $groupModel->find($id);
        if (!$group) {
            error('组信息不存在', 500);
        }
        $groupModel->updateRow($id, [$field => $value]);

        // 更新到redis
        $redis = new Redis();
        $cacheKey = sprintf(CacheKey::GROUPINFO, $id);
        $cache = $redis->hget($cacheKey, 'group_no');
        if (empty($cache)) {
            $data = $group;
            $data[$field] = $value;
            $redis->hmset($cacheKey, $data);
        } else {
            $redis->hset($cacheKey, $field, $value);
        }

        return '保存成功';
    }

    /**
     * 新增组信息
     */
    public function saveNewGroup()
    {
        $groupNo = trim(post('group_no', ''));
        $groupName = trim(post('group_name', ''));
        $shellLink = trim(post('shell_link', ''));
        $country = trim(post('country', ''));
        $remark = trim(post('remark', ''));
        $groupModel = new GroupInfo();

        // 验证
        $group = $groupModel->have(['group_no' => $groupNo]);
        if ($group) {
            error('该组号已经存在', 500);
        }
        if (!in_array($country, ['de', 'it', 'jp', 'fr', 'us'])) {
            error('国家选择错误');
        }
        if (empty($groupName)) {
            error('组名不能为空');
        }
        if (empty($shellLink)) {
            error('脚本链接不能为空');
        }
        if (!str_starts_with($shellLink, 'http')) {
            error('脚本链接必须是一个URL');
        }

        $groupId = $groupModel->save([
            'group_no' => $groupNo,
            'country' => $country,
            'group_name' => $groupName,
            'shell_link' => $shellLink,
            'remark' => $remark
        ]);

        // 添加到redis
        $redis = new Redis();
        $cacheKey = sprintf(CacheKey::GROUPINFO, $groupId);
        $redis->hmset($cacheKey, $groupModel->find($groupId));

        if ($groupId) {
            return '新增成功';
        }
        error('新增失败', 500);
    }

    /**
     * 域名统计
     */
    public function domains()
    {
        $view = new \core\lib\View(VIEWS);
        // 所有组号
        $groupNos = array_unique((new GroupInfo())->listAll(['ORDER' => ['id' => 'DESC']], 'group_no'));
        return $view->render('groupstat_domains', [
            'group_nos' => $groupNos
        ]);
    }

    /**
     * 获取事件条件
     */
    public function whereRangeDate($dateRange = '')
    {
        if (empty($dateRange) || !in_array($dateRange, ['0-3', '0-5', '0-7', '0', '-1', '-2'])) {
            $dateRange = '0';
        }
        $today = date('Y-m-d');
        $yesterday = date('Y-m-d', strtotime("-1 day"));
        $qianday = date('Y-m-d', strtotime("-2 days"));
        if ($dateRange === '0') {
            return $today;
        } elseif ($dateRange === '-1') {
            return $yesterday;
        } elseif ($dateRange === '-2') {
            return $qianday;
        } elseif ($dateRange === '0-3') {
            return [$today, $yesterday, $qianday];
        } elseif ($dateRange === '0-5') {
            return [$today, $yesterday, $qianday, date('Y-m-d', strtotime("-3 days")), date('Y-m-d', strtotime("-4 days"))];
        } elseif ($dateRange === '0-7') {
            return [
                $today, $yesterday, $qianday,
                date('Y-m-d', strtotime("-3 days")), date('Y-m-d', strtotime("-4 days")),
                date('Y-m-d', strtotime("-5 days")), date('Y-m-d', strtotime("-6 days"))
            ];
        }
        return [];
    }

    /**
     * 异步获取域名统计数据
     */
    public function getDomainsData()
    {
        $page = intval(post('page', 1));
        $pageSize = intval(post('limit', 20));
        $groupNo = trim(post('group_no', ''));
        $domain = trim(post('domain', ''));
        $dateRange = trim(post('date_range', ''));
        $sortField = trim(post('sort_field', '')); // 排序字段
        $sortOrder = trim(post('sort_order', '')); // 排序类型：desc（降序）、asc（升序）、null（空对象，默认排序）
        $jumpStatModel = new JumpStatDomain();
        $orderField = 'num_pv';
        $orderSort = 'DESC';
        if (!empty($sortField) && !empty($sortOrder) && in_array($sortOrder, ['asc', 'desc'])) {
            $orderField = $sortField;
            $orderSort = strtoupper($sortOrder);
        }
        $whereStr = 'total_pv > 500';
        !empty($groupNo) && $whereStr .= " and group_no='" . $groupNo . "'";
        !empty($domain) && $whereStr .= " and domain='" . $domain . "'";
        $dateRange = $this->whereRangeDate($dateRange);
        if (is_string($dateRange)) {
            $whereStr .= " and stat_date='" . $dateRange . "'";
        } elseif (is_array($dateRange)) {
            $whereStr .= " and stat_date in('" . join("','", $dateRange) . "')";
        }

        $limitStart = ($page - 1) * $pageSize;
        $sql = <<<SQL
SELECT `group_no`,`domain`,sum(num_pv) AS num_pv,sum(total_pv) AS total_pv
from jump_stat_pv
where {$whereStr}
GROUP BY `group_no`,`domain`
ORDER BY $orderField $orderSort 
LIMIT $limitStart,$pageSize
SQL;
        $sql2 = <<<SQL
SELECT distinct `group_no`,`domain`
from jump_stat_domain
where {$whereStr}
SQL;
        $list = $jumpStatModel->query($sql)->fetchAll();
        $total = count($jumpStatModel->query($sql2)->fetchAll());

        if (!empty($list)) {
            $star = $page > 1 ? ($page - 1) * $pageSize : 0;
            foreach ($list as $k => &$item) {
                $item['id'] = $star + $k + 1;
                $item['rate_pv'] = ($item['total_pv'] > 0 ? ($item['num_pv'] == $item['total_pv'] ? 100 : round($item['num_pv'] * 100 / $item['total_pv'], 2)) : 0) . '%';
            }
        }

        layuiRet($list, $total);
    }

    /**
     * 导出Excel，根据条件查询后，访问比例降序排序并且大于1%的数据
     */
    public function exportDomainsData()
    {
        $groupNo = trim(post('group_no', ''));
        $domain = trim(post('domain', ''));
        $dateRange = trim(post('date_range', ''));
        // 创建一个新的excel文档
        require_once(VENDOR . '/autoload.php');
        $spreadsheet = new Spreadsheet();
        // 获取当前操作sheet的对象
        $worksheet = $spreadsheet->getActiveSheet();
        // 设置当前sheet的标题
        $worksheet->setTitle('组域名统计-' . date('Ymd'));
        // 设置宽度为true,不然太窄了
        $spreadsheet->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);
        $spreadsheet->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
        $spreadsheet->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);

        //设置第一条的标题
        $worksheet->setCellValue('A1', '组号')->setCellValue('B1', '域名')
            ->setCellValue('C1', 'PV')->setCellValue('D1', '总PV')->setCellValue('E1', 'PV比例');

        // 设置粗体
        $spreadsheet->getActiveSheet()->getStyle('A1:E1')->getFont()->setBold(true);

        // 开始赋值
        $jumpStatModel = new JumpStatDomain();
        $orderField = 'num_pv';
        $orderSort = 'DESC';
        if (!empty($sortField) && !empty($sortOrder) && in_array($sortOrder, ['asc', 'desc'])) {
            $orderSort = strtoupper($sortOrder);
        }
        $whereStr = 'total_pv > 500';
        !empty($groupNo) && $whereStr .= " and group_no='" . $groupNo . "'";
        !empty($domain) && $whereStr .= " and domain='" . $domain . "'";
        $dateRange = $this->whereRangeDate($dateRange);
        if (is_string($dateRange)) {
            $whereStr .= " and stat_date='" . $dateRange . "'";
        } elseif (is_array($dateRange)) {
            $whereStr .= " and stat_date in('" . join("','", $dateRange) . "')";
        }

        $sql = <<<SQL
SELECT `group_no`,`domain`,sum(num_pv) AS num_pv,sum(total_pv) AS total_pv
from jump_stat_pv
where {$whereStr}
GROUP BY `group_no`,`domain`
ORDER BY $orderField $orderSort
SQL;
        $list = $jumpStatModel->query($sql)->fetchAll();

        if ($list) {
            $data = [];
            foreach ($list as $item) {
                $ratePv = ($item['total_pv'] > 0 ? ($item['num_pv'] == $item['total_pv'] ? 100 : round($item['num_pv'] * 100 / $item['total_pv'], 2)) : 0);
                $item['rate_pv'] = $ratePv;
                $data[] = $item;
            }
            if (!empty($data)) {
                foreach ($data as $k => $item) {
                    $i = $k + 2;
                    $worksheet->setCellValue("A{$i}", $item['group_no'])
                        ->setCellValue("B{$i}", $item['domain'])
                        ->setCellValue("C{$i}", $item['num_pv'])
                        ->setCellValue("D{$i}", $item['total_pv'])
                        ->setCellValue("E{$i}", $item['rate_pv']);
                }
            }
        }

        // 注意这边文件名不能带中文
        $filename = 'groupstat-domain-' . date('YmdHi');
        $format = 'xls';

        return downloadExcel($spreadsheet, $filename, $format);
    }

    /**
     * ip图标统计1
     */
    public function ipechart1()
    {
        $view = new \core\lib\View(VIEWS);
        return $view->render('groupstat_ipechart1', [
            'v' => time(),
        ]);
    }

    /**
     * ip图标统计1
     */
    public function ipechart2()
    {
        $view = new \core\lib\View(VIEWS);
        return $view->render('groupstat_ipechart2', [
            'v' => time(),
        ]);
    }
}